package com.da.im.handler;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONException;
import com.da.im.ImServer;
import com.da.im.common.Command;
import com.da.im.common.type.CommandType;
import com.da.im.common.WsResult;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.atomic.AtomicReference;

/**
 * @author da
 * @time 2023/12/20 上午 9:33
 * 处理websocket连接
 */
@Slf4j
public class WebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame frame) throws Exception {
        try {
            //解析连接
            Command command = JSON.parseObject(frame.text(), Command.class);
            // java17的新switch写法
            switch (CommandType.match(command.getCode())) {
                //处理连接
                case CONNECTION -> ConnectHandler.execute(ctx, command);
                //收发消息
                case CHAT -> ChatHandler.execute(ctx, frame.text());
                default -> ctx.channel().writeAndFlush(WsResult.error("不支持的code类型"));
            }
        } catch (JSONException e) {
            ctx.channel().writeAndFlush(WsResult.error("发送消息格式有误,请检查输入"));
        } catch (Exception e) {
            ctx.channel().writeAndFlush(WsResult.error(e.getMessage()));
        }
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        if (ImServer.USERS.containsValue(ctx.channel())) {
            AtomicReference<String> user = new AtomicReference<>("");
            ImServer.USERS.forEach((k, v) -> {
                if (v == ctx.channel()) {
                    user.set(k);
                }
            });
            String key = user.get();
            //移除原来的
            ImServer.USERS.remove(key);
            //群消息通知用户离线
            ImServer.USERS.values().forEach(channel -> {
                channel.writeAndFlush(WsResult.success(key + "离开了,当前在线的用户有:" + ImServer.USERS.keySet()));
            });
            log.error("用户{}断开连接", key);
        }
    }
}
